/**
 * 视频管理Hook
 * 处理视频列表、文件上传和URL生成
 */

import { useState, useCallback, useRef, useEffect } from 'react'
import type { VideoItem } from '../component/VideoSelector'
import { PRESET_VIDEOS, getVideoFileError, VIDEO_CONFIG } from '../config/videos'
import { detectVideosInPublicFolder, refreshVideoList } from '../utils/videoDetector'

interface UseVideoManagerOptions {
  defaultVideos?: VideoItem[]
  onVideoChange?: (video: VideoItem) => void
}

interface UseVideoManagerReturn {
  videos: VideoItem[]
  currentVideoId: string | undefined
  currentVideo: VideoItem | undefined
  selectVideo: (video: VideoItem) => void
  uploadVideo: (file: File) => Promise<void>
  removeVideo: (videoId: string) => void
  addVideo: (video: VideoItem) => void
  clearUploadedVideos: () => void
  refreshVideos: () => Promise<void>
  isLoading: boolean
}

export function useVideoManager(options: UseVideoManagerOptions = {}): UseVideoManagerReturn {
  const { defaultVideos = PRESET_VIDEOS, onVideoChange } = options
  
  const [videos, setVideos] = useState<VideoItem[]>([])
  const [currentVideoId, setCurrentVideoId] = useState<string | undefined>()
  const [isLoading, setIsLoading] = useState(true)
  const uploadedVideoUrls = useRef<Set<string>>(new Set())

  const currentVideo = videos.find(v => v.id === currentVideoId)

  // 初始化时检测视频文件
  useEffect(() => {
    const initializeVideos = async () => {
      setIsLoading(true)
      try {
        const detectedVideos = await detectVideosInPublicFolder()
        if (detectedVideos.length > 0) {
          setVideos(detectedVideos)
          if (!currentVideoId) {
            setCurrentVideoId(detectedVideos[0].id)
            onVideoChange?.(detectedVideos[0])
          }
        } else {
          // 如果没有检测到视频，使用默认列表
          setVideos(defaultVideos)
          if (!currentVideoId && defaultVideos.length > 0) {
            setCurrentVideoId(defaultVideos[0].id)
            onVideoChange?.(defaultVideos[0])
          }
        }
      } catch (error) {
        // console.error('初始化视频列表失败:', error)
        setVideos(defaultVideos)
        if (!currentVideoId && defaultVideos.length > 0) {
          setCurrentVideoId(defaultVideos[0].id)
          onVideoChange?.(defaultVideos[0])
        }
      } finally {
        setIsLoading(false)
      }
    }

    initializeVideos()
  }, []) // eslint-disable-line react-hooks/exhaustive-deps

  // 选择视频
  const selectVideo = useCallback((video: VideoItem) => {
    setCurrentVideoId(video.id)
    onVideoChange?.(video)
  }, [onVideoChange])

  // 上传视频文件
  const uploadVideo = useCallback(async (file: File): Promise<void> => {
    try {
      // 检查文件格式和大小
      const error = getVideoFileError(file)
      if (error) {
        throw new Error(error)
      }

      // 创建本地URL
      const url = URL.createObjectURL(file)
      uploadedVideoUrls.current.add(url)

      // 获取视频元数据
      const videoMetadata = await getVideoMetadata(file)
      
      const newVideo: VideoItem = {
        id: `uploaded-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
        name: file.name.replace(/\.[^/.]+$/, ''), // 移除文件扩展名
        url,
        duration: videoMetadata.duration,
        thumbnail: videoMetadata.thumbnail,
        description: `上传的视频 • ${formatFileSize(file.size)}`
      }

      setVideos(prev => [newVideo, ...prev])
      setCurrentVideoId(newVideo.id)
      onVideoChange?.(newVideo)
    } catch (error) {
      // console.error('视频上传失败:', error)
      throw error
    }
  }, [onVideoChange])

  // 移除视频
  const removeVideo = useCallback((videoId: string) => {
    const video = videos.find(v => v.id === videoId)
    if (video && uploadedVideoUrls.current.has(video.url)) {
      URL.revokeObjectURL(video.url)
      uploadedVideoUrls.current.delete(video.url)
    }

    setVideos(prev => prev.filter(v => v.id !== videoId))
    
    if (currentVideoId === videoId) {
      const remainingVideos = videos.filter(v => v.id !== videoId)
      const nextVideo = remainingVideos[0]
      if (nextVideo) {
        setCurrentVideoId(nextVideo.id)
        onVideoChange?.(nextVideo)
      } else {
        setCurrentVideoId(undefined)
      }
    }
  }, [videos, currentVideoId, onVideoChange])

  // 添加视频
  const addVideo = useCallback((video: VideoItem) => {
    setVideos(prev => [...prev, video])
  }, [])

  // 清空上传的视频
  const clearUploadedVideos = useCallback(() => {
    // 释放所有上传视频的URL
    uploadedVideoUrls.current.forEach(url => {
      URL.revokeObjectURL(url)
    })
    uploadedVideoUrls.current.clear()

    // 只保留默认视频
    setVideos(defaultVideos)
    
    if (currentVideoId && !defaultVideos.find(v => v.id === currentVideoId)) {
      const firstDefault = defaultVideos[0]
      if (firstDefault) {
        setCurrentVideoId(firstDefault.id)
        onVideoChange?.(firstDefault)
      } else {
        setCurrentVideoId(undefined)
      }
    }
  }, [defaultVideos, currentVideoId, onVideoChange])

  // 刷新视频列表
  const refreshVideos = useCallback(async () => {
    setIsLoading(true)
    try {
      const detectedVideos = await refreshVideoList()
      if (detectedVideos.length > 0) {
        // 保留上传的视频
        const uploadedVideos = videos.filter(v => v.url.startsWith('blob:'))
        const allVideos = [...detectedVideos, ...uploadedVideos]
        setVideos(allVideos)
        
        // 如果当前视频不存在了，选择第一个
        if (currentVideoId && !allVideos.find(v => v.id === currentVideoId)) {
          const firstVideo = allVideos[0]
          if (firstVideo) {
            setCurrentVideoId(firstVideo.id)
            onVideoChange?.(firstVideo)
          }
        }
      }
    } catch (error) {
      // console.error('刷新视频列表失败:', error)
    } finally {
      setIsLoading(false)
    }
  }, [videos, currentVideoId, onVideoChange])

  return {
    videos,
    currentVideoId,
    currentVideo,
    selectVideo,
    uploadVideo,
    removeVideo,
    addVideo,
    clearUploadedVideos,
    refreshVideos,
    isLoading
  }
}

// 获取视频元数据
async function getVideoMetadata(file: File): Promise<{
  duration: string
  thumbnail?: string
}> {
  return new Promise((resolve) => {
    const video = document.createElement('video')
    const url = URL.createObjectURL(file)
    
    video.preload = 'metadata'
    video.src = url
    
    video.onloadedmetadata = () => {
      const duration = formatDuration(video.duration)
      
      // 生成缩略图
      generateThumbnail(video).then(thumbnail => {
        URL.revokeObjectURL(url)
        resolve({ duration, thumbnail })
      }).catch(() => {
        URL.revokeObjectURL(url)
        resolve({ duration })
      })
    }
    
    video.onerror = () => {
      URL.revokeObjectURL(url)
      resolve({ duration: '未知' })
    }
  })
}

// 生成视频缩略图
async function generateThumbnail(video: HTMLVideoElement): Promise<string> {
  return new Promise((resolve, reject) => {
    video.currentTime = Math.min(1, video.duration * VIDEO_CONFIG.seekPreviewPosition)
    
    video.onseeked = () => {
      try {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        
        if (!ctx) {
          reject(new Error('无法创建canvas上下文'))
          return
        }
        
        canvas.width = VIDEO_CONFIG.thumbnailWidth
        canvas.height = VIDEO_CONFIG.thumbnailHeight
        
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
        const thumbnail = canvas.toDataURL('image/jpeg', VIDEO_CONFIG.thumbnailQuality)
        resolve(thumbnail)
      } catch (error) {
        reject(error)
      }
    }
  })
}

// 格式化时长
function formatDuration(seconds: number): string {
  if (isNaN(seconds) || seconds < 0) return '0:00'
  
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = Math.floor(seconds % 60)
  
  if (hours > 0) {
    return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
  } else {
    return `${minutes}:${secs.toString().padStart(2, '0')}`
  }
}

// 格式化文件大小
function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

export default useVideoManager
